package com.joelaws.prototype.client.service;

import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.gwtext.client.core.EventObject;
import com.gwtext.client.widgets.Button;
import com.gwtext.client.widgets.HTMLPanel;
import com.gwtext.client.widgets.MessageBox;
import com.gwtext.client.widgets.Panel;
import com.gwtext.client.widgets.Toolbar;
import com.gwtext.client.widgets.ToolbarButton;
import com.gwtext.client.widgets.event.ButtonListenerAdapter;
import com.gwtext.client.widgets.form.FormPanel;
import com.gwtext.client.widgets.form.Label;
import com.gwtext.client.widgets.form.TextArea;
import com.gwtext.client.widgets.form.TextField;
import com.gwtext.client.widgets.layout.AnchorLayout;
import com.gwtext.client.widgets.layout.FormLayout;
import com.joelaws.prototype.client.data.Message;
import com.joelaws.prototype.client.data.User;
import com.joelaws.prototype.client.rpc.Manage;
import com.joelaws.prototype.client.rpc.ManageAsync;
import com.joelaws.prototype.client.rpc.Messaging;
import com.joelaws.prototype.client.rpc.MessagingAsync;
import com.joelaws.prototype.client.util.Create;

public class MessagingTab extends Panel {

	final private User user;

	final Panel body;

	public MessagingTab(User user) {
		this.user = user;
		body = new Panel();
		setLayout(new AnchorLayout());

		setAutoScroll(true);
		setBorder(false);
		setFrame(true);

		add(getMainPanel());

		setTitle("Messaging");
	}

	private Panel getMainPanel() {
		Panel panel = new Panel();

		final ToolbarButton compose = new ToolbarButton("Compose");
		final ToolbarButton inbox = new ToolbarButton("Inbox");
		final ToolbarButton sent = new ToolbarButton("Sent");

		ButtonListenerAdapter listener = new ButtonListenerAdapter() {

			public void onClick(Button button, EventObject e) {
				if (button == compose) {
					System.out.println("Compose");
					body.clear();
					body.add(getComposePanel());
					body.doLayout();
				} else if (button == inbox) {
					System.out.println("Inbox");
					body.clear();
					body.add(getInboxPanel());
					body.doLayout();
				} else if (button == sent) {
					System.out.println("Sent");
					body.clear();
					body.add(getSentPanel());
					body.doLayout();
				} else {
					System.out.println("Unknown button");
				}
			}
		};

		compose.addListener(listener);
		inbox.addListener(listener);
		sent.addListener(listener);

		Toolbar toolbar = new Toolbar();
		toolbar.addButton(compose);
		toolbar.addButton(inbox);
		toolbar.addButton(sent);

		panel.setTopToolbar(toolbar);
		panel.add(body);

		return panel;
	}

	private Panel getComposePanel() {
		FormPanel formPanel = new FormPanel();
		formPanel.setAutoScroll(true);
		formPanel.setLayout(new FormLayout());

		final TextField to = new TextField("To", "to");
		formPanel.add(to);

		final TextField subject = new TextField("Subject", "subject");
		formPanel.add(subject);

		final TextArea body = new TextArea("Body", "body");
		formPanel.add(body);

		final Label label = new Label("");
		formPanel.add(label);

		formPanel.add(new Button("Send", new ButtonListenerAdapter() {

			public void onClick(Button button, EventObject e) {
				Message message = new Message(user.getUserID(), Long.parseLong(to.getText()), subject.getText(), body
						.getText());
				MessagingAsync instance = Messaging.Util.getInstance();
				instance.storeMessage(message, new AsyncCallback<Object>() {

					public void onFailure(Throwable caught) {
						label.setText("Error saving: " + caught.getMessage());
					}

					public void onSuccess(Object arg0) {
						MessageBox.alert("Sent");

					}
				});
			}
		}));
		return formPanel;
	}

	private Panel getComposePanel(final User otherUser) {
		FormPanel formPanel = new FormPanel();
		formPanel.setAutoScroll(true);
		formPanel.setLayout(new FormLayout());

		final TextField to = new TextField("To", "to");
		to.setValue(otherUser.getFirstName() + " " + otherUser.getLastName());
		formPanel.add(to);

		final TextField subject = new TextField("Subject", "subject");
		formPanel.add(subject);

		final TextArea body = new TextArea("Body", "body");
		formPanel.add(body);

		final Label label = new Label("");
		formPanel.add(label);

		formPanel.add(new Button("Send", new ButtonListenerAdapter() {

			public void onClick(Button button, EventObject e) {
				Message message = new Message(user.getUserID(), otherUser.getUserID(), subject.getText(), body
						.getText());
				MessagingAsync instance = Messaging.Util.getInstance();
				instance.storeMessage(message, new AsyncCallback<Object>() {

					public void onFailure(Throwable caught) {
						label.setText("Error saving: " + caught.getMessage());
					}

					public void onSuccess(Object arg0) {
						MessageBox.alert("Sent");

					}
				});
			}
		}));
		return formPanel;
	}

	private Panel getInboxPanel() {
		final Panel panel = new Panel();

		MessagingAsync instance = Messaging.Util.getInstance();

		instance.getToMessages(user.getUserID(), this.getMessageCallback(panel));

		return panel;
	}

	private Panel getSentPanel() {
		final Panel panel = new Panel();

		MessagingAsync instance = Messaging.Util.getInstance();

		instance.getFromMessages(user.getUserID(), this.getMessageCallback(panel));

		return panel;
	}

	private AsyncCallback<List<Message>> getMessageCallback(final Panel panel) {
		return new AsyncCallback<List<Message>>() {

			public void onFailure(Throwable caught) {
				System.out.println("faileddddddddd " + caught.getMessage());
			}

			public void onSuccess(final List<Message> messages) {

				if (messages == null) {
					System.out.println("Found no messages");
					return;
				}
				System.out.println("Found " + messages.size() + " messages");
				Set<Long> userIDs = Create.newSet();
				for (Message message : messages) {
					if (user.getUserID() == message.getFromUser()) {
						userIDs.add(message.getToUser());
					} else {
						userIDs.add(message.getFromUser());
					}
				}

				ManageAsync manage = Manage.Util.getInstance();
				long[] arr = new long[userIDs.size()];
				int i = 0;
				for (Long l : userIDs) {
					arr[i] = l;
					i++;
				}

				manage.getUsers(arr, new AsyncCallback<Map<Long, User>>() {

					public void onFailure(Throwable caught) {
						System.out.println("Failed in getUsers in message tab");
					}

					public void onSuccess(Map<Long, User> result) {
						if (result == null) {
							return;
						}
						result.put(user.getUserID(), user);
						for (Message message : messages) {
							final User fromUser = result.get(message.getFromUser());
							final User toUser = result.get(message.getToUser());
							if (fromUser == null || toUser == null) {
								System.out.println("FOUND NO USER FOR MESSAGE " + message.getFromUser() + " "
										+ message.getToUser());
							}
							panel.add(new HTMLPanel("<br/><br/>From: " + fromUser.getFirstName() + " "
									+ fromUser.getLastName() + "<br/>To: " + toUser.getFirstName() + " "
									+ toUser.getLastName() + "<br/>Subject: " + message.getSubject() + "<br/>Body:"
									+ message.getBody()));
							if (fromUser != user) {
								panel.add(new Button("Reply", new ButtonListenerAdapter() {

									public void onClick(Button button, EventObject e) {
										body.clear();
										body.add(getComposePanel(fromUser));
										body.doLayout();
									}
								}));
							}
						}
						panel.doLayout();

					}
				});
			}
		};
	}

}
